﻿using System;
using System.Web;
using System.Web.Mvc;
using System.Web.Caching;
using System.IO;
using System.IO.Compression;
using System.Text;
using Fat.Mvc.Helpers.IO;

namespace Fat.Mvc.Web.Controllers
{
    public class ZipController : Controller
    {
        IFileBase file;
        const int cacheForMins = 60;

        public ZipController() : this(null) { }
        public ZipController(IFileBase fileBase)
        {
            this.file = fileBase ?? new FileBase();
        }

        byte[] GetBytesFromCache(string path)
        {
            object fromCache = HttpRuntime.Cache.Get(path);
            if (fromCache == null) return null;

            try
            {
                return fromCache as byte[];
            }
            catch
            {
                //the object in the cache wasn't a byte array 
                //that's sad and perplexing... 
                return null;
            }
        }

        public virtual void Image(string path)
        {
            //verify that this path is valid... 
            //and leads to a public image file, 
            //not to a private file, or a strip club 

            var server = HttpContext.Server;
            string decodedPath = server.UrlDecode(path);
            string mappedPath = server.MapPath(decodedPath);
            byte[] imageBytes = GetBytesFromCache(mappedPath);

            if (imageBytes == null)
            {
                imageBytes = file.ReadAllBytes(mappedPath);

                //cache image src 
                HttpRuntime.Cache.Insert(
                    path,
                    imageBytes,
                    null, //or: new CacheDependency(mappedPath), 
                    Cache.NoAbsoluteExpiration,
                    TimeSpan.FromMinutes(cacheForMins));
            }

            Response.Cache.SetCacheability(HttpCacheability.Public);
            Response.Cache.SetExpires(Cache.NoAbsoluteExpiration);
            Response.AddFileDependency(mappedPath);
            Response.Cache.SetLastModifiedFromFileDependencies();
            Response.AppendHeader("Content-Length", imageBytes.Length.ToString());
            Response.ContentType = "image/jpeg";
            Response.OutputStream.Write(imageBytes, 0, imageBytes.Length);
            Response.Flush();
        }
    }
}
